package com.example.sppmode.Common;

import android.util.Log;

import com.example.sppmode.Common.Utils;

public class MyByteQueue {
    private static final String TAG = "MyByteQueue";

    private static final int QUEUE_SIZE_MAX = (1024 * 2);
    private static final int QUEUE_SIZE_MIN = (10);

    private String queueName;
    private final byte[] queue;
    private int front;
    private int rear;

    public MyByteQueue(String name, int size) {
        if (size < QUEUE_SIZE_MIN)
            size = QUEUE_SIZE_MIN;

        if (size > QUEUE_SIZE_MAX)
            size = QUEUE_SIZE_MAX;

        if (name == null)
            queueName = "";
        else
            queueName = name;
        queue = new byte[size];
        front = 0;
        rear = 0;
    }

    /**
     * 销毁队列
     */
    public void clear() {
        front = 0;
        rear = 0;
    }

    /**
     * 获取队列容量
     *
     * @return queue容量
     */
    public int size() {
        return queue.length;
    }

    /**
     * 判断队列是否为空
     *
     * @return true空，false非空
     */
    public boolean isEmpty() {
        return front == rear;
    }

    /**
     * 获取队列长度
     *
     * @return queue 元素个数
     */
    public int length() {
        if (front > rear) {
            return (front - rear);
        } else if (front < rear) {
            return (size() - rear + front);
        }

        return 0;
    }

    /**
     * 一个元素进队
     *
     * @param b 元素
     * @return 0：无错，-1：队列长度达到最大容量
     */

    public int enQueue(byte b) {
        synchronized (queue) {
            if (front - rear >= queue.length) {
                /* queue full */
                return -1;
            }

            queue[front % queue.length] = b;
            front++;
        }
        return 0;
    }

    /**
     * bytes.length个元素进队
     *
     * @param bytes 元素数组
     * @return 0：无错，-1：队列长度达到最大容量， -2：元素数组非法
     */
    public int enQueue(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            /* invalid data */
            return -2;
        }

        synchronized (queue) {
            Log.d(TAG, queueName + " enQueue, bytes=" + Utils.convertByteArray2HexStr(bytes, bytes.length));
            Log.d(TAG, queueName + " enQueue, front=" + front + ", rear=" + rear + ", length()=" + length());

            if(length() > 0) {
                byte[] tempData = peekQueue(length());
                Log.d(TAG, queueName + " enQueue, before=" + Utils.convertByteArray2HexStr(tempData, tempData.length));
            }

            if (length() == size()) {
                /* queue full */
                return -1;
            }

            if (size() - length() < bytes.length) {
                /* There's not enough space */
                return -2;
            }

            for (byte b : bytes) {
                if(front >= size())
                    front = 0;
                queue[front++] = b;
            }

            if(length() > 0) {
                byte[] tempData = peekQueue(length());
                Log.d(TAG, queueName + " enQueue, after=" + Utils.convertByteArray2HexStr(tempData, tempData.length));
            }
        }

        return 0;
    }

    /**
     * 出队，使用此方法前需要调用isEmpty()方法判断队列是否为空，
     * 不为空才能调用此方法，否则取得数是非法的。
     *
     * @return 出队元素
     */
    public byte deQueue() {
        byte b;

        synchronized (queue) {
            if(rear >= size())
                rear = 0;
            b = queue[rear++];
        }
        return b;
    }

    /**
     * deCnt个元素出队，如果队列中元素小于deCnt，则返回实际个数
     *
     * @param deCnt 出队个数
     * @return 出队元素数据
     */
    public byte[] deQueue(int deCnt) {
        byte[] bytes;

        synchronized (queue) {
            if (isEmpty()) {
                return null;
            }

            if (length() < deCnt)
                deCnt = length();

            bytes = new byte[deCnt];
            for (int i = 0; i < deCnt; i++) {
                if(rear >= size())
                    rear = 0;
                bytes[i] = queue[rear++];
            }
        }

        return bytes;
    }

    /**
     * 查看队首元素
     *
     * @return 查看一个元素
     */
    public byte peekQueue() {
        byte b;

        synchronized (queue) {
            int peekIndex = rear;
            if(peekIndex >= size())
                peekIndex = 0;
            b = queue[peekIndex];
        }

        return b;
    }

    /**
     * 查看peekCnt个元素
     *
     * @param peekCnt 查看数量
     * @return 查看元素数组
     */
    public byte[] peekQueue(int peekCnt) {
        byte[] bytes;

        synchronized (queue) {
            if (isEmpty()) {
                return null;
            }

            if (length() < peekCnt)
                peekCnt = length();

            bytes = new byte[peekCnt];
            int peekIndex = rear;

            for (int i = 0; i < peekCnt; i++) {
                if(peekIndex >= size())
                    peekIndex = 0;
                bytes[i] = queue[peekIndex++];
            }
        }

        return bytes;
    }
}
